<?php

/**
 * 分页
 *
 * @author haifeng.wu
 */

class Project_Paginator
{

    /**
     * url模板内容，标签如下：
     * {file}：分当前的文件URL路径
     * {params}：分页的参数集
     * {page}：当前页数
     *
     * @var string
     */
    public $urlTemplateContent = '{file}?{params}&page={page}';

    /**
     * 分页中的列表模板内容，标签如下：
     * {listInsideItem}：列表里面的项
     *
     * @var string
     */
    public $itemListTemplateContent = '&nbsp;{listInsideItem}&nbsp;';

    /**
     * 分页中的列最多个数
     *
     * @var integer
     */
    public $itemListSize = 9;
    
    /**
     * 分页模板内容，标签如下：
     * {recordCount}：总记录数
     * {pageSize}：每页显示记录数
     * {currentPage}：当前页数
     * {pageCount}：总页数
     * {recordStart}：开始记录数
     * {recordEnd}：结束记录数
     * {itemFirst}：第一页链接
     * {itemLast}：最后一页链接
     * {itemPrevious}：上一页记录数
     * {itemNext}：下一页记录数
     * {itemList}：列表记录数
	 * {itemInput}：手动输入分页
     *
     * @var string
     */
    public $pageTemplateContent = '共{recordCount}条记录，每页{pageSize}条 页次：<span><font class="orange">{currentPage}</font>/{pageCount}</span>&nbsp;&nbsp; {itemFirst} {itemPrevious} {itemList} {itemNext} {itemLast}';

    /**
     * 分页项内容
     * $array = 
     *
     * @var array
     */
    public $itemArray = array('next' => '下一页', 'previous' => '上一页', 'first' => '首页', 'last' => '尾页');

    /**
     * 总记录数
     *
     * @var integer
     */
    protected $_recordCount = 0;

    /**
     * 每页显示记录数
     *
     * @var integer
     */
    protected $_pageSize = 20;

    /**
     * 当前页数
     *
     * @var integer
     */
    protected $_currentPage = 0;

    /**
     * 总页数
     *
     * @var integer
     */
    protected $_pageCount;

    /**
     * 开始的记录数(从多少条开始)
     *
     * @var integer
     */
    protected $_recordStart;

    /**
     * 结束的记录数(从多少条开始，到多少条结束的)
     *
     * @var integer
     */
    protected $_recordEnd;

    /**
     * 分页需要传递的数据
     *
     * @var array
     */
    protected $_paramsArray = array();
    
    /**
     * description
     * @param  integer $recordCount
     * @param  integer $pageSize
     * @param  integer $currentPage
     * 
     * @return void
     */
    public function __construct($recordCount, $pageSize = 20, $currentPage = 0)
    {
        $this->_recordCount = $recordCount;
        $this->_pageSize = $pageSize;
        $this->_pageCount = ceil($recordCount/$pageSize);
        if ($currentPage == 0) {
            if (isset($_REQUEST['page'])) {
                $currentPage = $_REQUEST['page'];
            } else {
                $currentPage = 1;
            }
        }
        $currentPage = intval($currentPage);
        if ($currentPage<1) {
            $currentPage = 1;
        }
        if ($currentPage>$this->_pageCount) {
            $currentPage = $this->_pageCount;
        }
        $this->_currentPage = $currentPage;
        $this->_recordStart = $recordCount > 0 ? $pageSize * ($currentPage-1) + 1 : 0;
        $this->_recordEnd = $this->_recordStart+$pageSize-1 >= $recordCount ? $recordCount : $this->_recordStart+$pageSize-1;
    }

    /**
     * 设置分页字符URL参数(动态分页使用)
     * 
     * @param  string $name
     * @param  string $value
     * @return void
     */
    public function addParams($name, $value='')
    {
        $this->_paramsArray[$name] = trim($value);
    }

    /**
     * 获取分页字符URL参数的值(动态分页使用)
     * 
     * @param  string $name
     * @return string
     */
    public function getParamsValue($name)
    {
        if (isset($this->_paramsArray[$name])) {
            $value = $this->_paramsArray[$name];
        }else{
            $value = '';
        }
        return $value;
    }

    /**
     * 删除分页字符URL参数的值(动态分页使用)
     * 
     * @param  string $name
     * @return void
     */
    public function removeParamsValue($name)
    {
        if (isset($this->_paramsArray[$name])) {
            unset($this->_paramsArray[$name]);
        }
    }

    /**
     * 获取总页数
     * 
     * @return integer
     */
    public function getPageCount()
    {
        return $this->_pageCount;
    }


    /**
     * 获取当前页数
     * 
     * @return integer
     */
    public function getCurrentPage()
    {
        return $this->_currentPage;
    }

    /**
     * 获取当页开始的记录数
     * 
     * @return integer
     */
    public function getRecordStart()
    {
        return $this->_recordStart;
    }

    /**
     * 获取当页结束的记录数
     * 
     * @return integer
     */
    public function getRecordEnd()
    {
        return $this->_recordEnd;
    }

    /**
     * 获得实际获取的记录数
     * 
     * @return integer
     */
    public function getRealPageSize()
    {
        if ($this->_recordCount > 0) {
            $num = $this->_recordEnd - $this->_recordStart + 1;
        } else {
            $num = 0;
        }
        return $num;
    }

    /**
     * 获取当页的URL
     * @param  array $page
     * @param  array $outParams
     * 
     * @return string
     */
    public function getUrl($page=0, $outParams = array())
    {
        /*解析URL模板*/
        $paramsString = '';
        foreach ($this->_paramsArray as $params=>$value) {
            if (in_array($params, $outParams)){
                continue;
            }
            $paramsString .= $paramsString != '' ? '&' : '';
            $paramsString .= "{$params}=" . urlencode($value);
        }
        $urlContent = $this->urlTemplateContent;
        $urlContent = str_replace('{file}', $_SERVER['PHP_SELF'], $urlContent);
        $urlContent = str_replace('{params}', $paramsString, $urlContent);
        if ($page == 0) {
            $page = $this->_currentPage;
        }
        $urlContent = str_replace('{page}', $page, $urlContent);
        
        return $urlContent;
    }

    /**
     * 获取分页HTML字符
     * 
     * @return string
     */
    public function getPageString()
    {
        /*解析URL模板*/
        $paramsString = '';
        foreach ($this->_paramsArray as $params=>$value) {
            $paramsString .= $paramsString != '' ? '&' : '';
            $paramsString .= "{$params}=" . urlencode($value);
        }
        
        $this->urlTemplateContent = str_replace(urlencode('{page}'), '{page}', $this->urlTemplateContent);
        $urlContent = $this->urlTemplateContent;
        $urlContent = str_replace('{file}', $_SERVER['PHP_SELF'], $urlContent);
        $urlContent = str_replace('{params}', $paramsString, $urlContent);

        /*计算出分页各项*/
        if ($this->_currentPage == 1 || $this->_recordCount==0) {//第一页项
            $itemFirst = "<span>{$this->itemArray['first']}</span>";
        } else {
            $itemFirst = "<a href=\"" . str_replace('{page}', '1', $urlContent) . "\"><span>{$this->itemArray['first']}</span></a>";
        }
        if ($this->_currentPage == $this->_pageCount) {//最后一页项
            $itemLast = "<span>{$this->itemArray['last']}</span>";
        } else {
            $itemLast = "<a href=\"" . str_replace('{page}', $this->_pageCount, $urlContent) . "\"><span>{$this->itemArray['last']}</span></a>";
        }
        if ($this->_currentPage > 1) {//上一页项
            $itemPrevious = "<a href=\"" . str_replace('{page}', $this->_currentPage-1, $urlContent) . "\"><span>{$this->itemArray['previous']}</span></a>";
        } else {
        	$itemPrevious = "<span>{$this->itemArray['previous']}</span>";  
        }
        if ($this->_currentPage < $this->_pageCount) {//下一页项
            $itemNext = "<a href=\"" . str_replace('{page}', $this->_currentPage+1, $urlContent) . "\"><span>{$this->itemArray['next']}</span></a>";
        } else {
            $itemNext = "<span>{$this->itemArray['next']}</span>"; 
        }
        //输入页数回车跳转项
        $itemInput = "<span><input type=\"text\" value=\"{$this->_currentPage}\" size=\"3\" onkeyup=\"var ___pageKeyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; if (___pageKeyCode == 13) {var ____pageVlue=this.value; if (____pageVlue.search(/[\d]+/)==-1){____pageVlue={$this->_currentPage};}____pageVlue=parseInt(____pageVlue); if (____pageVlue<1){____pageVlue=1;} if (____pageVlue>{$this->_pageCount}){____pageVlue={$this->_currentPage};} this.value=____pageVlue;  location.href='{$urlContent}'.replace(/\{page\}/g, this.value);}
\"></span>";
        /*列表项*/
        $listLeftSize = floor($this->itemListSize / 2);
        $listRightSize = $this->itemListSize - $listLeftSize ;
        $listStart = $this->_currentPage - $listLeftSize;
        $listStart = $listStart > 1 ? $listStart : 1;//修正
        $listEnd = $listStart + $this->itemListSize - 1;
        $listEnd = $listEnd < $this->_pageCount ? $listEnd : $this->_pageCount;//修正
        if ($listEnd == $this->_pageCount) {
            $listStart = $listEnd + 1 - $this->itemListSize;
            $listStart = $listStart > 1 ? $listStart : 1;//修正
        }
        $itemList = '';
        if ($listStart > 1) {
        	$listUrlContent = str_replace('{page}', 1, $urlContent);
            $itemList .= str_replace('{listInsideItem}', "<a href=\"{$listUrlContent}\">1...</a>", $this->itemListTemplateContent);
        }
        for ($i = $listStart; $i <= $listEnd; $i++) {
        	if ($i == $this->_currentPage) {
        	    $itemList .= str_replace('{listInsideItem}', "<span>{$i}</span>", $this->itemListTemplateContent);
        	} else {
        		$listUrlContent = str_replace('{page}', $i, $urlContent);
        	    $itemList .= str_replace('{listInsideItem}', "<a href=\"{$listUrlContent}\">{$i}</a>", $this->itemListTemplateContent);
        	}
        }
        if ($listEnd < $this->_pageCount) {
        	$listUrlContent = str_replace('{page}', $this->_pageCount, $urlContent);
            $itemList .= str_replace('{listInsideItem}', "<a href=\"{$listUrlContent}\">...{$this->_pageCount}</a>", $this->itemListTemplateContent);
        }

        /*解析分页模板*/
        $pageContent = $this->pageTemplateContent;
        $pageContent = str_replace('{recordCount}', $this->_recordCount, $pageContent);
        $pageContent = str_replace('{pageSize}', $this->_pageSize, $pageContent);
        $pageContent = str_replace('{currentPage}', $this->_currentPage, $pageContent);
        $pageContent = str_replace('{pageCount}', $this->_pageCount, $pageContent);
        $pageContent = str_replace('{recordStart}', $this->_recordStart, $pageContent);
        $pageContent = str_replace('{recordEnd}', $this->_recordEnd, $pageContent);
        $pageContent = str_replace('{itemFirst}', $itemFirst, $pageContent);
        $pageContent = str_replace('{itemLast}', $itemLast, $pageContent);
        $pageContent = str_replace('{itemPrevious}', $itemPrevious, $pageContent);
        $pageContent = str_replace('{itemNext}', $itemNext, $pageContent);
        $pageContent = str_replace('{itemList}', $itemList, $pageContent);
        $pageContent = str_replace('{itemInput}', $itemInput, $pageContent);

        return $pageContent;
    }
}